package org.lcc.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.lcc.mapper.ExaminationmanagementMapper;
import org.lcc.mapper.UserMapper;
import org.lcc.model.entity.Exam;
import org.lcc.model.entity.ExamNotification;
import org.lcc.model.entity.User;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class ExamNotificationJob implements Job {

    @Autowired
    private ExaminationmanagementMapper examinationmanagementMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JavaMailSender mailSender;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LocalDateTime now = LocalDateTime.now();
        log.info("正在检查考试通知，当前时间：{}", now);
        // 获取所有状态有效且即将开始的考试
        List<Exam> upcomingExams = examinationmanagementMapper.selectUpcomingExams(now);
        log.info("找到 {} 场即将开始的考试", upcomingExams.size());

        for (Exam exam : upcomingExams) {
            LocalDateTime startTime = exam.getStartTime();
            long daysUntilExam = ChronoUnit.DAYS.between(now, startTime);
            log.info("考试：{}，开始时间：{}，距离考试开始的天数：{}",
                    exam.getExamName(), startTime, daysUntilExam);

            // 获取需要为这场考试发送通知的学生
            List<String> studentIds = examinationmanagementMapper.getStudentIdsForExam(exam.getExamId());
            log.info("为考试 {}({}) 找到 {} 名学生", exam.getExamId(), exam.getSubject()+exam.getExamName(), studentIds.size());

            List<String> studentsWithoutEmail = new ArrayList<>();

            for (String schoolNumber : studentIds) {
                // 根据 school_number 查询用户
                User student = userMapper.selectOne(new QueryWrapper<User>()
                        .eq("school_number", schoolNumber));
                
                if (student == null || student.getEmail() == null || student.getEmail().trim().isEmpty()) {
                    log.warn("学号为 {} 的学生未找到或没有邮箱", schoolNumber);
                    studentsWithoutEmail.add(student != null ? student.getRealName() : schoolNumber);
                    continue;
                }

                // 检查是否已经发送过通知
                if (daysUntilExam == 3) {
                    // 检查是否已经发送过三天前的通知
                    int count = examinationmanagementMapper.selectNotificationCount(
                        exam.getExamId(), 
                        schoolNumber, 
                        "考试前三天",
                        true
                    );
                    
                    if (count == 0) {
                        // 发送三天前的通知
                        boolean sent = sendExamNotification(exam, student);
                        // 记录通知状态
                        ExamNotification notification = new ExamNotification();
                        notification.setExamId(exam.getExamId());
                        notification.setStudentId(schoolNumber);
                        notification.setNotificationType("考试前三天");
                        notification.setNotificationTime(now);
                        notification.setStatus(sent);
                        notification.setUniqueIdentifier(sent ? "已成功发送三天前通知" : "发送失败：学生未设置邮箱地址");
                        examinationmanagementMapper.insertNotification(notification);
                    }
                } else if (daysUntilExam == 1) {
                    // 检查是否已经发送过一天前的通知
                    int count = examinationmanagementMapper.selectNotificationCount(
                        exam.getExamId(),
                        schoolNumber,
                        "考试前一天",
                        true
                    );
                    
                    if (count == 0) {
                        // 发送一天前的通知
                        boolean sent = sendExamNotification(exam, student);
                        
                        // 记录通知状态
                        ExamNotification notification = new ExamNotification();
                        notification.setExamId(exam.getExamId());
                        notification.setStudentId(schoolNumber);
                        notification.setNotificationType("考试前一天");
                        notification.setNotificationTime(now);
                        notification.setStatus(sent);
                        notification.setUniqueIdentifier(sent ? "已成功发送一天前通知" : "发送失败：学生未设置邮箱地址");
                        examinationmanagementMapper.insertNotification(notification);
                    }
                }
            }

            // 如果有学生没有邮箱，记录到日志中
            if (!studentsWithoutEmail.isEmpty()) {
                log.warn("以下学生没有邮箱地址，无法发送通知：{}", String.join("、", studentsWithoutEmail));
            }
        }
    }

    private boolean sendExamNotification(Exam exam, User student) {
        if (student.getEmail() == null || student.getEmail().isEmpty()) {
            log.warn("学生 {} 没有邮箱地址，无法发送考试通知", student.getRealName());
            return false;
        }

        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(student.getEmail());
            message.setFrom("859697179@qq.com");
            message.setSubject("考试通知 - " + exam.getExamName());

            String content = String.format(
                    "尊敬的考生：%s\n\n" +
                            "您有一场考试即将开始，以下是考试相关信息：\n\n" +
                            "考试名称：%s\n" +
                            "考试科目：%s\n" +
                            "考试开始时间：%s\n" +
                            "考试时长：%d分钟\n" +
                            "试卷总分：%d分\n\n" +
                            "请提前做好准备，准时参加考试。\n\n" +
                            "NERV考试系统",
                    student.getRealName() != null ? student.getRealName() : student.getUsername(),
                    exam.getExamName(),
                    exam.getSubject(),
                    exam.getStartTime().toString().replace("T", " "),
                    exam.getDuration(),
                    exam.getTotalScore()
            );

            message.setText(content);
            mailSender.send(message);
            log.info("成功向 {}({}) 发送邮件通知", student.getRealName(), student.getSchoolNumber());
            return true;
        } catch (Exception e) {
            log.error("发送邮件通知失败", e);
            return false;
        }
    }
} 